package edu.ccut.saturn.studio.logic.model.saturn;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.swt.graphics.Image;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

import edu.ccut.saturn.studio.Activator;
import edu.ccut.saturn.studio.Images;
import edu.ccut.saturn.studio.core.search.IObserver;
import edu.ccut.saturn.studio.core.search.SaturnFileSearcher;
import edu.ccut.saturn.studio.core.search.SaturnFileSearcher.SearchResult;
import edu.ccut.saturn.studio.core.util.eclipse.Messages;
import edu.ccut.saturn.studio.core.util.freemaker.FreemarkerUtils;
import edu.ccut.saturn.studio.core.util.xml.SaturnW3CUtil;
import edu.ccut.saturn.studio.dialog.SelectionCandidate;
import edu.ccut.saturn.studio.dialog.workflowdialog.SaturnWorkflowDialogInLogic;
import edu.ccut.saturn.studio.export.createhtml.Parameters;
import edu.ccut.saturn.studio.logic.figure.SaturnFigure;
import edu.ccut.saturn.studio.logic.model.Shape;
import edu.ccut.saturn.studio.logic.model.xml.loader.StartNodeLoader;

public class SaturnWorkflowNodeInLogic extends Shape {

	private static final long serialVersionUID = 1L;

	public static final String KEY_NODE_WORKFLOW = "workflow";
	public static final String SHOW_NODE_WORKFLOW = Messages.getString("SaturnWorkflowNodeInLogic.workflow"); //$NON-NLS-1$
	
	public static final String SHOW_WORKFLOW_EXCEPTION_IN_LOGIC = "exception";
	
	public static final String SHOW_WORKFLOW_NAME_IN_LOGIC = "name";
	
	public static final String SHOW_WORKFLOW_KEY_IN_LOGIC = "key";

	public static final String SHOW_WORKFLOW_VERSION_IN_LOGIC = "version";
	
	public static final String SHOW_WORKFLOW_CREATOR_IN_LOGIC = "creator";
	
	public static final String SHOW_WORKFLOW_DESCRIPTION_IN_LOGIC = "description";

	public static final String SHOW_WORKFLOW_PARAMETERS_IN_LOGIC = "parameters";
	
	public static final String SHOW_WORKFLOW_TRANSACTION_IN_LOGIC = "transaction";
	
	public static final String SHOW_WORKFLOW_TRANSACTIONTYPE_IN_LOGIC = "transactionType";
	
	public static final String SHOW_WORKFLOW_TYPE_IN_LOGIC = "type";
	
	private static int number = 1;
	
	private String exception = "";
	
	private String key = "";
	
	private String version = "";
	
	private String creator = "";
	
	private String transactionType = SelectionCandidate.transactionTypesForLogic[0];
	
	private Image image = Activator.getImage(Images.WORK_FLOW_BIG);
	
	public SaturnWorkflowNodeInLogic(){
		super.setName(SHOW_NODE_WORKFLOW + number++);
		super.setSize(new Dimension(50, 70));
	}
	
	@Override
	public Image getIcon() {
		return image;
	}
	
	public Image getSmallIcon() {
		return Activator.getImage(Images.WORK_FLOW_SMALL);
	}
	
	@Override
	protected void setImage(Image image) {
		this.image = image;
	}
	
	@Override
	public IFigure getFigure() {
		SaturnFigure saturnFigure = new SaturnFigure();
		saturnFigure.setIcon(image);
		saturnFigure.setName(super.getName());

		return saturnFigure;
	}
	
	public List<SaturnParameter> getListParameter(Document document) {
		StartNodeLoader start = new StartNodeLoader();
		Element ele = document.getDocumentElement();
		List<Shape> starts = start.loadNodes(ele);
		for (Shape s : starts) {
			return s.getParameters();
		}
		return new ArrayList<SaturnParameter>();
	}

	public String getException() {
		return exception;
	}

	public void setException(String exception) {
		if(!this.exception.equals(exception)){
			this.exception = exception;
			firePropertyChange(SHOW_WORKFLOW_EXCEPTION_IN_LOGIC, null, exception);
		}
	}

	public String getKey() {
		return key;
	}

	public void setKey(String key) {
		if(!this.key.equals(key)){
			this.key = key;
			firePropertyChange(SHOW_WORKFLOW_KEY_IN_LOGIC, null, key);
		}
	}

	public String getVersion() {
		return version;
	}

	public void setVersion(String version) {
		if (!this.version.equals(version)) {
			this.version = version;
			firePropertyChange(SHOW_WORKFLOW_VERSION_IN_LOGIC, null, version);
		}
	}

	public String getCreator() {
		return creator;
	}

	public void setCreator(String creator) {
		if (!this.creator.equals(creator)) {
			this.creator = creator;
			firePropertyChange(SHOW_WORKFLOW_CREATOR_IN_LOGIC, null, creator);
		}
	}

	public String getTransactionType() {
		return transactionType;
	}

	public void setTransactionType(String transactionType) {
		if (!this.transactionType.equals(transactionType)) {
			this.transactionType = transactionType;
			firePropertyChange(SHOW_WORKFLOW_TRANSACTIONTYPE_IN_LOGIC, null, transactionType);
		}
	}

	@Override
	public Node doRefresh() {
		Node root = super.getRoot();

		Node workflowNode = SaturnW3CUtil.createChildNode(root,
				KEY_NODE_WORKFLOW, null);
		
		SaturnW3CUtil.createAttribute(workflowNode, SHOW_WORKFLOW_EXCEPTION_IN_LOGIC, this.exception);
		
		SaturnW3CUtil.createChildNode(workflowNode, SHOW_WORKFLOW_KEY_IN_LOGIC, this.key);
		
		SaturnW3CUtil.createChildNode(workflowNode, SHOW_WORKFLOW_NAME_IN_LOGIC, super.getName());
		
		SaturnW3CUtil.createChildNode(workflowNode, SHOW_WORKFLOW_VERSION_IN_LOGIC, this.version);
		
		this.createTransactionType(workflowNode);
		
		if(super.getParameters().size()==0){
			SaturnParameter o = new SaturnParameter();
			o.setId("1");
			o.setName("creator");
			o.setClassType("java.lang.String");
			o.setPassingType("in");
			o.setScope("logic");
			super.getParameters().add(o);
		}
		
		super.createParemeters(workflowNode);
		
		return workflowNode;
	}
	
	/**
	 * 创建Logic的transactionType
	 * 
	 */
	public void createTransactionType(Node node) {
	
		Node transactionNode = SaturnW3CUtil.createChildNode(node, SHOW_WORKFLOW_TRANSACTION_IN_LOGIC, null);

		SaturnW3CUtil.createAttribute(transactionNode, SHOW_WORKFLOW_TYPE_IN_LOGIC, this.transactionType);
	}

	@Override
	public Dialog getDialog() {
		SaturnWorkflowDialogInLogic dialog = new SaturnWorkflowDialogInLogic(
				super.getShell(), this);
		super.reorder(this);
		return dialog;
	}
	
	@Override
	public Shape cloneShape(Point mousePoint, Shape shape) {
		return null;
	}
	
	public List<SearchResult> keyMapInWorkspace(IObserver observer) {
		
		List<SearchResult> list = null;
		String[] suffixes = {"wf"};
		
		try {
			list = SaturnFileSearcher.getValueAndDocumentMapInWorkspace(suffixes , observer, null);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return list;
	}
	
	
	public List<SearchResult> keyMapInProject(IObserver observer) {
		List<SearchResult> list = null;
		
		try {
			list = SaturnFileSearcher.getValueAndDocumentMapInProject(super.findTheProject(), "wf",
					observer, null);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return list;
}

	@Override
	public Parameters createNodeHtml(String filePath, String[] tempnames) {

		List<Parameters> basicvaluse = new ArrayList<Parameters>();
		Map<String, List<?>> summm = new HashMap<String, List<?>>();
		List<SaturnParameter> parameters = getParameters();
		String name = getName();
		Parameters para = new Parameters();
		
		para.setName(getName());
		para.setId(getId());
		para.setKey(getKey());
		para.setVersion(getVersion());
		para.setDescription(getDescription());
		para.setCreator(parameters.get(parameters.size()-1).getValueKey().trim());
		para.setTransactiontype(getTransactionType());
	 	basicvaluse.add(para);
		
		para.setInfourl( name + "-workflow.html");
		para.setInfoname( name);
		para.setDescription(getDescription());
		para.setNodeType(Messages.getString("Logic.WorkFlow")); //$NON-NLS-1$
		para.setImagename("workflow");
		parameters.remove(parameters.size()-1);
		summm.put("parameters", parameters);
		summm.put("basicvaluse", basicvaluse);
		String templatePath = "template/export/logic/workflow";
		String Path = filePath + File.separator + name + "-workflow.html";
		FreemarkerUtils.writeTemplateToFile(templatePath,summm, Path);
		
		return para;
	}
}
